home *** CD-ROM | disk | FTP | other *** search
- /* +-------------------------------------------------------------------+ */
- /* | Copyright 1992, 1993, David Koblas (koblas@netcom.com) | */
- /* | | */
- /* | Permission to use, copy, modify, and to distribute this software | */
- /* | and its documentation for any purpose is hereby granted without | */
- /* | fee, provided that the above copyright notice appear in all | */
- /* | copies and that both that copyright notice and this permission | */
- /* | notice appear in supporting documentation. There is no | */
- /* | representations about the suitability of this software for | */
- /* | any purpose. this software is provided "as is" without express | */
- /* | or implied warranty. | */
- /* | | */
- /* +-------------------------------------------------------------------+ */
-
- #include <X11/Intrinsic.h>
- #include <X11/StringDefs.h>
- #include <X11/cursorfont.h>
- #include "xpaint.h"
- #include "misc.h"
- #include "Paint.h"
-
- #define FILL 0x2
- #define POLY 0x1
- #define IsPoly(x) (x & POLY)
- #define IsFill(x) (x & FILL)
-
- typedef struct {
- Boolean flag;
- int startX, startY, lastX, lastY;
- GC gc1, gc2;
- int npoints, size;
- XPoint *points, *real;
- } LocalInfo;
-
- static void press(Widget w, LocalInfo *l, XButtonEvent *event, OpInfo *info)
- {
- XRectangle undo;
-
- if (info->surface == opWindow)
- return;
-
- if ((event->state &
- (Button1Mask|Button2Mask|Button3Mask|Button4Mask|Button5Mask)) != 0)
- return;
-
- l->lastX = l->startX = event->x;
- l->lastY = l->startY = event->y;
- l->npoints = 0;
- if (IsFill(l->flag)) {
- l->points[l->npoints].x = event->x;
- l->points[l->npoints].y = event->y;
- l->real[l->npoints].x = info->x;
- l->real[l->npoints].y = info->y;
- l->npoints++;
- }
-
- undo.x = event->x;
- undo.y = event->y;
- undo.width = 1;
- undo.height = 1;
-
- if (event->button == Button2)
- {
- l->gc1 = info->second_gc;
- l->gc2 = info->first_gc;
- }
- else
- {
- l->gc1 = info->first_gc;
- l->gc2 = info->second_gc;
- }
-
- UndoStartPoint(w, info, event->x, event->y);
-
- XDrawLine(XtDisplay(w), info->drawable, l->gc1,
- l->lastX, l->lastY, event->x, event->y);
- if (!info->isFat)
- XDrawLine(XtDisplay(w), XtWindow(w), l->gc1,
- l->lastX, l->lastY, event->x, event->y);
-
- PwUpdate(w, &undo, False);
- }
-
- static void motion(Widget w, LocalInfo *l, XMotionEvent *event, OpInfo *info)
- {
- XRectangle undo;
-
- if (info->surface == opWindow)
- return;
-
- XDrawLine(XtDisplay(w), info->drawable,l->gc1,
- l->lastX, l->lastY, event->x, event->y);
- if (!info->isFat)
- XDrawLine(XtDisplay(w), XtWindow(w), l->gc1,
- l->lastX, l->lastY, event->x, event->y);
-
- UndoGrow(w, event->x, event->y);
-
- undo.x = MIN(l->lastX, event->x);
- undo.y = MIN(l->lastY, event->y);
- undo.width = MAX(l->lastX, event->x) - undo.x + 1;
- undo.height = MAX(l->lastY, event->y) - undo.y + 1;
-
- l->lastX = event->x;
- l->lastY = event->y;
- if (IsFill(l->flag)) {
- l->points[l->npoints].x = event->x;
- l->points[l->npoints].y = event->y;
- l->real[l->npoints].x = info->x;
- l->real[l->npoints].y = info->y;
- l->npoints++;
- if (l->npoints > l->size - 3) {
- l->size += 256;
- l->real = (XPoint*)XtRealloc((XtPointer)l->real,
- sizeof(XPoint) * l->size);
- l->points = (XPoint*)XtRealloc((XtPointer)l->points,
- sizeof(XPoint) * l->size);
- }
- }
-
- PwUpdate(w, &undo, False);
- }
- static void release(Widget w, LocalInfo *l, XButtonEvent *event, OpInfo *info)
- {
- XRectangle undo;
-
- int mask;
- /*
- ** Check to make sure all buttons are up, before doing this
- */
- mask = Button1Mask|Button2Mask|Button3Mask|Button4Mask|Button5Mask;
- switch (event->button) {
- case Button1: mask ^= Button1Mask; break;
- case Button2: mask ^= Button2Mask; break;
- case Button3: mask ^= Button3Mask; break;
- case Button4: mask ^= Button4Mask; break;
- case Button5: mask ^= Button5Mask; break;
- }
- if ((event->state & mask) != 0)
- return;
- l->points[l->npoints].x = event->x;
- l->points[l->npoints].y = event->y;
- l->real[l->npoints].x = info->x;
- l->real[l->npoints].y = info->y;
- l->npoints++;
-
- UndoGrow(w, event->x, event->y);
-
- undo.x = MIN(l->lastX, event->x);
- undo.y = MIN(l->lastY, event->y);
- undo.width = MAX(l->lastX, event->x) - undo.x + 1;
- undo.height = MAX(l->lastY, event->y) - undo.y + 1;
-
- if (IsFill(l->flag)) {
- if (!info->isFat)
- XFillPolygon(XtDisplay(w), XtWindow(w), l->gc2,
- l->real, l->npoints, Complex, CoordModeOrigin);
- XFillPolygon(XtDisplay(w), info->drawable, l->gc2,
- l->real, l->npoints, Complex,CoordModeOrigin);
- l->points[l->npoints].x = l->points[0].x;
- l->points[l->npoints].y = l->points[0].y;
- l->real[l->npoints].x = l->real[0].x;
- l->real[l->npoints].y = l->real[0].y;
- l->npoints++;
- if (!info->isFat)
- XDrawLines(XtDisplay(w), XtWindow(w), l->gc1,
- l->real, l->npoints, CoordModeOrigin);
- XDrawLines(XtDisplay(w), info->drawable, l->gc1,
- l->real, l->npoints, CoordModeOrigin);
- }
- else
- {
- l->lastX = event->x;
- l->lastY = event->y;
- XDrawLine(XtDisplay(w), info->drawable,l->gc1,
- l->lastX, l->lastY, l->startX, l->startY);
- if (!info->isFat)
- XDrawLine(XtDisplay(w), XtWindow(w), l->gc1,
- l->lastX, l->lastY, l->startX, l->startY);
-
- }
-
- PwUpdate(w, NULL, False);
- }
-
- /*
- ** Those public functions
- */
- void *FreehandAdd(Widget w)
- {
- LocalInfo *l = (LocalInfo*)XtMalloc(sizeof(LocalInfo));
-
- XtVaSetValues(w, XtNcompress, False, NULL);
- l->flag = 0;
-
- l->size = 256;
- l->real = (XPoint*)XtCalloc(sizeof(XPoint), l->size);
- l->points = (XPoint*)XtCalloc(sizeof(XPoint), l->size);
-
- OpAddEventHandler(w, opPixmap, ButtonPressMask, FALSE, (OpEventProc)press, l);
- OpAddEventHandler(w, opPixmap, ButtonMotionMask, FALSE, (OpEventProc)motion, l);
- OpAddEventHandler(w, opPixmap, ButtonReleaseMask, FALSE, (OpEventProc)release, l);
- SetPencilCursor(w);
-
- return l;
- }
- void FreehandRemove(Widget w, LocalInfo *l)
- {
- OpRemoveEventHandler(w, opPixmap, ButtonPressMask, FALSE, (OpEventProc)press, l);
- OpRemoveEventHandler(w, opPixmap, ButtonMotionMask, FALSE, (OpEventProc)motion, l);
- OpRemoveEventHandler(w, opPixmap, ButtonReleaseMask, FALSE, (OpEventProc)release, l);
-
- XtFree((XtPointer)l->real);
- XtFree((XtPointer)l->points);
- XtFree((XtPointer)l);
- }
- void *FFreehandAdd(Widget w)
- {
- LocalInfo *l = (LocalInfo*)XtMalloc(sizeof(LocalInfo));
- l->flag = FILL;
-
- l->size = 256;
- l->real = (XPoint*)XtCalloc(sizeof(XPoint), l->size);
- l->points = (XPoint*)XtCalloc(sizeof(XPoint), l->size);
-
- XtVaSetValues(w, XtNcompress, True, NULL);
-
- OpAddEventHandler(w, opPixmap, ButtonPressMask, FALSE, (OpEventProc)press, l);
- OpAddEventHandler(w, opPixmap, ButtonMotionMask, FALSE, (OpEventProc)motion, l);
- OpAddEventHandler(w, opPixmap, ButtonReleaseMask, FALSE, (OpEventProc)release, l);
-
- SetPencilCursor(w);
-
- return l;
- }
- void FFreehandRemove(Widget w, LocalInfo *l)
- {
- OpRemoveEventHandler(w, opPixmap, ButtonPressMask, FALSE, (OpEventProc)press, l);
- OpRemoveEventHandler(w, opPixmap, ButtonMotionMask, FALSE, (OpEventProc)motion, l);
- OpRemoveEventHandler(w, opPixmap, ButtonReleaseMask, FALSE, (OpEventProc)release, l);
- XtFree((XtPointer)l->real);
- XtFree((XtPointer)l->points);
- XtFree((XtPointer)l);
- }
-